package com.miplus.ccrm.core.api.bailian;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.alibaba.dashscope.app.ApplicationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.miplus.ccrm.core.api.bailian.model.AgentRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Service
public class BaiLianService {
    /**
     * 应用ID
     */
    private static final String API_KEY = "sk-15cb2fe048c6409d9aa2ffb2ddf71bf6";
    @Autowired
    private Application application;
    /**
     * 非流式对话
     *
     * @param request
     * @return
     * @throws NoApiKeyException
     * @throws InputRequiredException
     */
    public ApplicationResult callWithSession(AgentRequest request) throws NoApiKeyException, InputRequiredException {
        String sessionid = request.getSessionId();
        String prompt = request.getPrompt();
        String appid = request.getAppId();
        if(StrUtil.isEmpty(appid) && StrUtil.isEmpty(prompt))
        {
            throw new InputRequiredException("appid or prompt is required");
        }
        ApplicationParam param = ApplicationParam.builder()
                .apiKey(API_KEY)
                .appId(appid)
                .sessionId(sessionid)
                .prompt(prompt)
                .build();
        ApplicationResult result = application.call(param);
        log.info("阻塞式AI请求结果：" + result);
        return result;
    }


    /**
     * 流式对话,不带参数，websocket连接和http请求,坐席和游客模式,不写库
     * @param request
     * @return
     * @throws NoApiKeyException
     * @throws InputRequiredException
     */

    public Flux<ApplicationResult> streamCallWithSession(AgentRequest request) throws NoApiKeyException, InputRequiredException {
        String sessionid = request.getSessionId();
        String prompt = request.getPrompt();
        String appid = request.getAppId();
        String channel = request.getChannel();
        Boolean isincrementalOutput = request.getIncrementalOutput(); //不填默认false
        if (StrUtil.isEmpty(sessionid) && StrUtil.isEmpty(prompt)) {
            throw new InputRequiredException("sessionId or prompt is required");
        }
        if (StrUtil.isNotEmpty(channel) && channel.equals("voice")) {
            log.info("语音机器人用户的问题：" + prompt);
        }
            log.info("坐席辅助用户的问题：" + prompt);
        ApplicationParam param = ApplicationParam.builder()
                .apiKey(API_KEY)
                .appId(appid)
                .sessionId(sessionid)
                .prompt(prompt)
                .incrementalOutput(isincrementalOutput)
                .build();
        //return Flux.from(application.streamCall(param));//直接返回
        // 仅收集finishReason为stop时的最终文本
        AtomicReference<String> finalResponse = new AtomicReference<>();//调试用
        return Flux.from(application.streamCall(param))
                .doOnNext(result -> {
                    // 记录每个流元素
                    log.info("stream request: {}", JSONUtil.toJsonStr(result))  ;

                    // 收集文本内容
                    if ("stop".equals(result.getOutput().getFinishReason())) {
                        finalResponse.set(result.getOutput().getText());
                    }
                })
                .doOnComplete(() -> {
                    // 流结束时记录完整响应和结束信息
                    log.info("stream complete");
                    log.info("AI完整回答: {}",  finalResponse.getAndSet(finalResponse.get()));
                })
                .doOnError(e -> log.error("流响应处理错误: {}", e.getMessage(), e));
    }
}
